import * as THREE from 'three';
import { useEffect, useRef } from 'react';
import "./index.less"
import { showFullScreenLoading, tryHideFullScreenLoading } from "@/config/serviceLoading";

//@ts-ignore
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
//@ts-ignore
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
//@ts-ignore
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
//@ts-ignore
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';

let mixer:any;


const Threejs = () => {
    const threeRef = useRef<HTMLDivElement>(null)

    useEffect(() => {

        const clock = new THREE.Clock();

        if(!threeRef.current) return

        const renderer = new THREE.WebGLRenderer( { antialias: true } );
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize( threeRef.current.clientWidth, threeRef.current.clientHeight );
        renderer.outputEncoding = THREE.sRGBEncoding;
        threeRef.current.appendChild( renderer.domElement );

        const pmremGenerator = new THREE.PMREMGenerator( renderer );

        const scene = new THREE.Scene();
        scene.background = new THREE.Color( 0xbfe3dd );
        scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture;

        const camera = new THREE.PerspectiveCamera( 40, threeRef.current.clientWidth / threeRef.current.clientHeight, 1, 100 );
        camera.position.set( 5, 2, 8 );

        const controls = new OrbitControls( camera, renderer.domElement );
        controls.target.set( 0, 0.5, 0 );
        controls.update();
        controls.enablePan = false;
        controls.enableDamping = true;

        const dracoLoader = new DRACOLoader();
        dracoLoader.setDecoderPath( '/draco/gltf/' );

        const loader = new GLTFLoader();
        loader.setDRACOLoader( dracoLoader );
        showFullScreenLoading()
        loader.load( '/models/LittlestTokyo.glb', function ( gltf:any ) {
            tryHideFullScreenLoading()
            const model = gltf.scene;
            model.position.set( 1, 1, 0 );
            model.scale.set( 0.01, 0.01, 0.01 );
            scene.add( model );

            mixer = new THREE.AnimationMixer( model );
            mixer.clipAction( gltf.animations[ 0 ] ).play();

            animate();

        }, undefined, function ( e:any ) {

            console.error( e );

        } );


        window.onresize = function () {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth, window.innerHeight );

        };


        function animate() {

            requestAnimationFrame( animate );

            const delta = clock.getDelta();

            mixer.update( delta );

            controls.update();

            renderer.render( scene, camera );

        }
    },[threeRef])

    return (
        <div className="three-container" ref={threeRef} id="three-container"></div>
    )
}

export default Threejs